package service

import (
	"fmt"
	"ginchat/models"
	"ginchat/utils"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

// FindUserByNameAndPwd
// @Tags 用户模块
// @Summary 登录
// @param name query string true "用户名"
// @param password query string true "密码"
// @Success 200 {string} data
// @Router /user/findUserByNameAndPwd [get]
func FindUserByNameAndPwd(c *gin.Context) {
	fmt.Println("FindUserByNameAndPwd")
	name := c.Request.FormValue("name")
	password := c.Request.FormValue("password")
	user := models.GetUserByName(name)
	if user.Name == "" {
		c.JSON(-1, gin.H{
			"message": "用户不存在",
			"code":    -1,
		})
		return
	}

	flag := utils.ValiPassword(password, user.Salt, user.Password)
	if !flag {
		c.JSON(200, gin.H{
			"code":    -1,
			"message": "密码不正确",
		})
		return
	}
	pwd := utils.MakePassword(password, user.Salt)
	data := models.GetUserByNameAndPwd(name, pwd)

	c.JSON(200, gin.H{
		"code":    0,
		"data":    data,
		"message": "操作成功",
	})
}

// GetUserList
// @Tags 用户模块
// @Summary 获取用户列表
// @Success 200 {string} data
// @Router /user/getUserList [get]
func GetUserList(c *gin.Context) {
	data := models.GetUserList()
	c.JSON(200, gin.H{
		"code":    0,
		"data":    data,
		"message": "操作成功",
	})
}

// CreateUserList
// @Tags 用户模块
// @Summary 新增用户
// @param name form string true "用户名"
// @param password form string true "密码"
// @param repassword form string true "确认密码"
// @Success 200 {string} data
// @Router /user/createUser [post]
func CreateUser(c *gin.Context) {
	user := models.UserBasic{}
	user.Name = c.Request.FormValue("name")
	password := c.Request.FormValue("password")
	repassword := c.Request.FormValue("repassword")
	println(password, repassword)
	if user.Name == "" || password == "" {
		c.JSON(-1, gin.H{
			"message": "用户名和密码不能为空",
			"code":    -1,
		})
		return
	}
	data := models.GetUserByName(user.Name)
	if data.Name != "" {
		c.JSON(-1, gin.H{
			"message": "用户名已存在",
			"code":    -1,
		})
		return
	}
	if password != repassword {
		c.JSON(-1, gin.H{
			"message": "两次密码不一致",
			"code":    -1,
		})
		return
	}
	salt := fmt.Sprintf("%06d", rand.Int31())
	user.Password = utils.MakePassword(password, salt)
	user.Salt = salt
	models.CreateUser(user)

	c.JSON(200, gin.H{
		"message": "创建成功",
		"code":    0,
		"data":    data,
	})
}

// DeleteUser
// @Tags 用户模块
// @Summary 删除用户
// @param id query string true "用户id"
// @Success 200 {string} data
// @Router /user/deleteUser [get]
func DeleteUser(c *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(c.Request.FormValue("id"))
	user.ID = uint(id)

	models.DeleteUser(user)

	c.JSON(200, gin.H{
		"message": "删除成功",
		"code":    0,
	})
}

// UpdateUser
// @Tags 用户模块
// @Summary 更新用户
// @param user body models.UserBasic true "用户信息"
// @Success 200 {string} data
// @Router /user/updateUser [post]
func UpdateUser(c *gin.Context) {
	user := models.UserBasic{}
	// id, _ := strconv.Atoi(c.PostForm("id"))
	// user.ID = uint(id)
	// user.Name = c.PostForm("name")
	// user.Password = c.PostForm("password")
	id, _ := strconv.Atoi(c.PostForm("id"))
	user.ID = uint(id)
	user.Name = c.PostForm("name")
	user.Password = c.PostForm("password")
	user.Phone = c.PostForm("phone")
	user.Avatar = c.PostForm("icon")
	user.Email = c.PostForm("email")
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	_, validateErr := govalidator.ValidateStruct(user)
	if validateErr != nil {
		c.JSON(200, gin.H{
			"message": validateErr.Error(),
			"code":    -1,
		})
		return

	}

	if user.ID == 0 {
		c.JSON(200, gin.H{
			"message": "Id不能为空",
			"code":    -1,
		})
		return
	}
	loginTime := time.Now() // 获取当前时间
	user.LoginTime = &loginTime

	models.UpdateUser(user)

	fmt.Println(user)

	c.JSON(200, gin.H{
		"message": "更新成功",
		"code":    0,
		"data":    user,
	})

}

// 防止跨域站点伪造请求
var upGrade = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// 发送消息给用户
// @Tags 用户模块
// @Summary 发送消息给用户
// @param message body models.Message true "消息体信息"
// @Success 200 {string} data
// @Router /user/SendUserMsg [post]
func SendUserMsg(c *gin.Context) {
	models.Chat(c.Writer, c.Request)
}

// 发送消息
// @Tags 用户模块
// @Summary 发送消息给用户
// @param message body models.Message true "消息体信息"
// @Success 200 {string} data
// @Router /user/SendMsg [post]
func SendMsg(c *gin.Context) {
	ws, err := upGrade.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(ws *websocket.Conn) {
		err = ws.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(ws)
	MsgHandler(ws, c)
}

// 发送websocket消息
func MsgHandler(ws *websocket.Conn, c *gin.Context) {
	fmt.Println("MsgHandler-------")
	for {

		msg, err := utils.Subscribe(c, utils.PublishKey)
		if err != nil {
			fmt.Println("发送失败：", err)
		}
		fmt.Println("发送的消息是-------", msg)
		tm := time.Now().Format("2006-01-02 15:04:05")
		m := fmt.Sprintf("[ws]%s:%s", tm, msg)
		err = ws.WriteMessage(1, []byte(m))
		if err != nil {
			fmt.Println(err)
		}
	}

}

// 获取好友列表
// @Tags 用户模块
// @Summary 获取好友列表
// @param {string} userId true "用户id"
// @Success 200 {string} data
// @Router /user/SendMsg [post]
func SearchFriends(c *gin.Context) {
	id, _ := strconv.Atoi(c.Request.FormValue("userId"))
	users := models.SearchFriends(uint(id))
	utils.RespOKList(c.Writer, users, len(users))

}

// 聊天
// @Tags 用户模块
// @Summary 聊天
// @param message body models.Message true "消息体信息"
// @Success 200 {string} data
// @Router /user/chat [post]
func Chat(c *gin.Context) {
	models.Chat(c.Writer, c.Request)
}

// 聊天
// @Tags 用户模块
// @Summary 添加好友
// @Param userId formData int true "用户id"
// @Param targetName formData string true "好友名"
// @Success 200 {string} data
// @Router /contact/addfriend [post]
func AddFriend(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Request.FormValue("userId"))
	// targetId, _ := strconv.Atoi(c.Request.FormValue("targetId"))
	targetName := c.Request.FormValue("targetName")
	// code, msg := models.AddFriend(uint(userId), targetId)
	code, msg := models.AddFriend(uint(userId), targetName)
	if code == 0 {
		utils.RespOK(c.Writer, code, msg)
	} else {
		utils.RespFail(c.Writer, msg)
	}
}

// 聊天
// @Tags 用户模块
// @Summary 根据id查询用户
// @Param userId formData int true "用户ID"
// @Success 200 {string} data
// @Router /user/find [post]
func FindByID(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Request.FormValue("userId"))
	data := models.FindById(uint(userId))
	utils.RespOK(c.Writer, data, "ok")
}

// @Tags 用户模块
// @Summary 创建群
// @Param ownerId formData int true "群主ID"
// @Param name formData string true "群名称"
// @Param icon formData string false "群图标"
// @Param desc formData string false "群描述"
// @Success 200 {string} data
// @Router /contact/createCommunity [post]
func CreateCommunity(c *gin.Context) {
	ownerId, _ := strconv.Atoi(c.Request.FormValue("ownerId"))
	name := c.Request.FormValue("name")
	icon := c.Request.FormValue("icon")
	desc := c.Request.FormValue("desc")
	community := models.Community{}
	community.OwnerId = uint(ownerId)
	community.Name = name
	community.Img = icon
	community.Desc = desc
	code, msg := models.CreateCommunity(&community)
	if code == 0 {
		utils.RespOK(c.Writer, code, msg)
	} else {
		utils.RespFail(c.Writer, msg)
	}
}

// @Tags 用户模块
// @Summary 加载群列表
// @Param ownerId formData int true "群主ID"
// @Success 200 {string} data
// @Router /contact/loadcommunity [post]
func LoadCommunity(c *gin.Context) {
	ownerId, _ := strconv.Atoi(c.Request.FormValue("ownerId"))
	data, msg := models.LoadCommunity(uint(ownerId))
	if len(data) != 0 {
		utils.RespList(c.Writer, 0, data, msg)
	} else {
		utils.RespFail(c.Writer, msg)
	}
}

// @Tags 用户模块
// @Summary 加载群列表
// @Param userId formData int true "群主ID"
// @Param comId formData string true "关键字"
// @Success 200 {string} data
// @Router /contact/joinGroup [post]
func JoinGroups(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Request.FormValue("userId"))
	keyword := c.Request.FormValue("comId")
	code, msg := models.JoinGroup(uint(userId), keyword)
	if code == 0 {
		utils.RespOK(c.Writer, code, msg)
	} else {
		utils.RespFail(c.Writer, msg)
	}
}

// @Tags 用户模块
// @Summary 加载历史消息
// @Param userIdA formData int true "发送者id"
// @Param userIdB formData int true "接收者id"
// @Param start formData int true "开始"
// @Param end formData int true "结束"
// @Param isRev formData bool true "是否接收"
// @Success 200 {string} data
// @Router /user/redisMsg [post]
func RedisMsg(c *gin.Context) {
	userIdA, _ := strconv.Atoi(c.PostForm("userIdA"))
	userIdB, _ := strconv.Atoi(c.PostForm("userIdB"))
	start, _ := strconv.Atoi(c.PostForm("start"))
	end, _ := strconv.Atoi(c.PostForm("end"))
	isRev, _ := strconv.ParseBool(c.PostForm("isRev"))
	res := models.RedisMsg(int64(userIdA), int64(userIdB), int64(start), int64(end), isRev)
	fmt.Println("RedisMsg>>>", res)
	utils.RespOKList(c.Writer, "ok", res)
}
